package com.why.simpleboot.core.core.aop.proxy;

import com.why.simpleboot.core.common.utils.SimpleReflectUtils;
import com.why.simpleboot.core.core.aop.entity.MethodInvocation;
import com.why.simpleboot.core.core.aop.interceptor.Interceptor;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @program: why-simpleboot-framework
 * @description:
 * @author: @why
 * @create: 2021-05-26 21:46
 **/
public class CglibProxy implements MethodInterceptor {

    private Object target;
    private Interceptor interceptor;

    public CglibProxy(Object target, Interceptor interceptor) {
        this.target = target;
        this.interceptor = interceptor;
    }


    public static Object wrapperBean(Object srcObject, Interceptor interceptor) {
        Enhancer enhancer = new Enhancer();
        Class<?> rootClass = srcObject.getClass();

        Class<?> superClass = rootClass;
//        说明当前类是代理类，那不行，得完成对父类的代理
        if (superClass.getName().contains("$$")) {
            superClass = rootClass.getSuperclass();
        }
        CglibProxy callBack = new CglibProxy(srcObject, interceptor);
        enhancer.setClassLoader(srcObject.getClass().getClassLoader());
        enhancer.setCallback(callBack);
        enhancer.setSuperclass(superClass);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        if (!NoProxyMethodName.NO_PROXY_METHODS.contains(method.getName())) {
            MethodInvocation invocation = new MethodInvocation(method, target, objects);
            return interceptor.proceed(invocation);
        } else {
            return SimpleReflectUtils.invokeMethod(target, method, objects);
        }
    }
}
